/******************************************************************************************************
Copyright (C) 2013 Mestrelab Research S.L. All rights reserved.

This file is part of the MNova scripting toolkit.

Authorized users of MNova Software may use this file freely, but this file is provided AS IS
with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
*****************************************************************************************************/

/*globals Application, DBPlugin, Dialog, qsTr, GroupBox, ComboBox, settings, LineEdit, MessageBox, DBDefinition, print*/
/*jslint plusplus: true, indent: 4*/

// Presents a dialog with option of selecting an existing database or creating and opening a new one.
// Returns the name of the selected database on success or undefined on failure.
function dbOpenDatabase() {
	"use strict";

	Application.mainWindow.doAction("dbConnect");
	if (!DBPlugin.client.connected()) {
		return;
	}

	var dbNames, preselected, dbi, showDBDialog, dbName, dbSchema, canOpenDB,
		dbNameSettingsKey = "Open Database",
		dbDialog = new Dialog(qsTr("Select Database")),
		gbExisting = new GroupBox(),
		gbNew = new GroupBox(),
		gbMain = new GroupBox(),
		cmbDB = new ComboBox(),
		leNewDB = new LineEdit();

	dbDialog.gbNewClicked = function (selected) {
		gbExisting.setChecked(!selected);
	};
	dbDialog.gbExistingClicked = function (selected) {
		gbNew.setChecked(!selected);
	};

	gbMain.title = qsTr("Select Database");

	gbExisting.title = qsTr("Existing Database:");
	gbExisting.checkable = true;
	gbExisting.checked = true;
	gbExisting.clicked.connect(dbDialog.gbExistingClicked);

	dbNames = DBPlugin.client.databases();
	preselected = settings.value(dbNameSettingsKey, "");
	for (dbi = 0; dbi < dbNames.length; dbi++) {
		cmbDB.addItem(dbNames[dbi]);
		if (dbNames[dbi] === preselected) {
			cmbDB.currentIndex = dbi;
		}
	}
	cmbDB.editable = false;
	gbExisting.add(qsTr("Name:"), cmbDB);

	gbNew.title = qsTr("New Database:");
	gbNew.checkable = true;
	gbNew.checked = false;
	gbNew.clicked.connect(dbDialog.gbNewClicked);

	leNewDB.label = "Name:";
	gbNew.add(leNewDB);

	gbMain.add(gbExisting);
	gbMain.add(gbNew);
	dbDialog.add(gbMain);

	dbName = undefined;
	while (true) {
		if (!dbDialog.exec()) {
			return undefined;
		}
		if (gbExisting.checked) {
			dbName = cmbDB.currentText;
			canOpenDB = true;
		} else if (gbNew.checked) {
			dbName = leNewDB.text.trim();
			if (leNewDB.text.length <= 0) {
				MessageBox.critical(qsTr("You must specify a database name."));
				leNewDB.setFocus();
				canOpenDB = false;
			} else if (dbNames.toString().indexOf(dbName) !== -1) {
				MessageBox.critical(qsTr("A database called '{0}' already exists.").format(dbName));
				leNewDB.setFocus();
				canOpenDB = false;
			} else if (!DBPlugin.client.createDatabase(DBDefinition.defaultDefinition(dbName))) {
				MessageBox.critical(qsTr("Could not create database '{0}'.").format(dbName));
				canOpenDB = false;
			} else {
				canOpenDB = true;
			}
		}
		if (canOpenDB) {
			if (!DBPlugin.client.openDatabase(dbName)) {
				MessageBox.critical(qsTr("Could not open database '{0}'.").format(dbName));
			} else {
				settings.setValue(dbNameSettingsKey, dbName);
				return dbName;
			}
		}
	}
}

// Creates a new database on the given server and returns its name, or undefiend on failure.
function createDatabase(aHost, aPort, aUser, aPassword, aDatabaseNameStem, aDatabaseDefinition) {
	"use strict";
	var dbnames, dbname, i, dbdef,
		db = DBPlugin.createClient();
	print(db.toString());

	// Connect: server, port, user, password [, database]
	db.connect(aHost, aPort, aUser, aPassword);
	if (!db.connected()) {
		MessageBox.critical(qsTr("Could not connect to server."));
		return undefined;
	}
	try {
		// Retrieve list of databases
		dbnames = db.databases();

		// Build a database name which doesnt exist yet
		dbname = aDatabaseNameStem;
		dbnames.contains = function (element) {
			var i;
			for (i = 0; i < this.length; i++) {
				if (this[i] === element) {
					return true;
				}
			}
			return false;
		};
		if (dbnames.contains(dbname)) {
			i = 1;
			while (dbnames.contains(aDatabaseNameStem + "_" + i)) {
				i++;
			}
			dbname = aDatabaseNameStem + "_" + i;
		}

		// Use default schema definition if none specified
		dbdef = aDatabaseDefinition;
		if (dbdef === undefined) {
			dbdef = DBDefinition.defaultDefinition(dbname);
		}
		dbdef.name = dbname;
		//print(dbdef);

		// Create the database
		if (db.createDatabase(dbdef)) {
			print("Database '" + dbname + "' created successfully.");
		} else {
			MessageBox.critical(qsTr("Could not create database '{0}'.").format(dbname));
			dbname = undefined;
		}
		db.disconnect();
		return dbname;
	} catch (e) {
		print(e);
		db.disconnect();
		return undefined;
	}
}
